/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
 *
 * @file    mapi_vgs.c
 * @brief   vgs server function
 * @author  HiMobileCam NDK develop team
 * @date  2019-8-7
 */

#include "mpi_vgs.h"
#include "mapi_comm_inner.h"
#include "hi_mapi_vgs_define.h"
#ifdef __DualSys__
#include "msg_server.h"
#endif

#define MAPI_FRAME_DATA_ADDR_NUM 3

static HI_S32 MAPI_VGS_SetFrameInfo(VIDEO_FRAME_S *videoFrame, const HI_MAPI_FRAME_DATA_S *frameData)
{
    HI_S32 ret;
    HI_U32 i;

    videoFrame->u32Width       = frameData->u32Width;
    videoFrame->u32Height      = frameData->u32Height;
    videoFrame->enField        = VIDEO_FIELD_FRAME;
    videoFrame->enPixelFormat  = frameData->enPixelFormat;
    videoFrame->enVideoFormat  = VIDEO_FORMAT_LINEAR;
    videoFrame->enCompressMode = frameData->enCompressMode;
    videoFrame->enDynamicRange = DYNAMIC_RANGE_SDR8;
    videoFrame->enColorGamut   = COLOR_GAMUT_BT601;
    videoFrame->u64PTS = frameData->u64pts;

    for (i = 0; i < MAPI_FRAME_DATA_ADDR_NUM; i++) {
        videoFrame->u32HeaderStride[i] = 0;  // Image compression header stride
        videoFrame->u64HeaderPhyAddr[i] = 0; // image compression header phyAddr
        videoFrame->u64HeaderVirAddr[i] = 0; //  image compression header virAddr
        videoFrame->u32Stride[i] = frameData->u32Stride[i];   // image data stride
        videoFrame->u64PhyAddr[i] = frameData->u64PhyAddr[i]; // image data phyAddr
        videoFrame->u64VirAddr[i] = frameData->u64VirAddr[i]; // image data virAddr
        videoFrame->u32ExtStride[i] = 0;  // 10 bit width data, the last 2bit data stride
        videoFrame->u64ExtPhyAddr[i] = 0; // 10 bit width data, the last 2bit data phyAddr
        videoFrame->u64ExtVirAddr[i] = 0; // 10 bit width data, the last 2bit data virAddr
    }

    videoFrame->s16OffsetTop = 0;
    videoFrame->s16OffsetBottom = 0;
    videoFrame->s16OffsetLeft = 0;
    videoFrame->s16OffsetRight = 0;

    videoFrame->u32MaxLuminance = MAPI_VIDEOFRAME_LUMINANCE_MAX;
    videoFrame->u32MinLuminance = MAPI_VIDEOFRAME_LUMINANCE_MIN;

    videoFrame->u32TimeRef = 0;

    videoFrame->u64PrivateData = 0;

    videoFrame->u32FrameFlag = 0;

    ret = memcpy_s(&videoFrame->stSupplement, sizeof(VIDEO_SUPPLEMENT_S),
        &frameData->stVideoSupplement, sizeof(VIDEO_SUPPLEMENT_S));
    MAPI_CHECK_RET(HI_MAPI_MOD_VGS, "memcpy_s", ret);

    return HI_SUCCESS;
}

HI_S32 HI_MAPI_VGS_RegMsg(HI_VOID)
{
#ifdef __DualSys__
    HI_S32 ret;

    ret = MAPI_MEDIA_MSG_RegMod(HI_MAPI_MOD_VGS, MAPI_MSG_GetVgsMod());
    if (ret != HI_SUCCESS) {
        MAPI_ERR_TRACE(HI_MAPI_MOD_VGS, "VGS Reg Msg error.\n");
        return HI_MAPI_VGS_EOPERATE_FAIL;
    }

#else
    MAPI_ERR_TRACE(HI_MAPI_MOD_ADEC, "VGS_RegMsg is no need in single system.\n");
#endif

    return HI_SUCCESS;
}

HI_S32 HI_MAPI_VGS_BeginJob(HI_HANDLE *vgsHdl)
{
    CHECK_MAPI_NULL_PTR_RET(HI_MAPI_MOD_VGS, vgsHdl, HI_MAPI_VGS_ENULL_PTR);

    HI_S32 ret;
    ret = HI_MPI_VGS_BeginJob((VGS_HANDLE *)vgsHdl);
    if (ret != HI_SUCCESS) {
        MAPI_ERR_TRACE(HI_MAPI_MOD_VGS, "HI_MPI_VGS_BeginJob fail, ret:%x\n", ret);
        return ret;
    }

    return HI_SUCCESS;
}

HI_S32 HI_MAPI_VGS_AddScaleTask(HI_HANDLE vgsHdl, const HI_MAPI_VGS_ScaleTaskAttr *scaleTaskAttr)
{
    CHECK_MAPI_NULL_PTR_RET(HI_MAPI_MOD_VGS, scaleTaskAttr, HI_MAPI_VGS_ENULL_PTR);
    CHECK_MAPI_BOOL_RET(HI_MAPI_MOD_VGS, vgsHdl != (HI_U32)HI_INVALID_HANDLE, HI_MAPI_VGS_EHANDLE_ILLEGAL);

    HI_S32 ret;
    VGS_TASK_ATTR_S vgsTask;
    VGS_SCLCOEF_MODE_E scaleCoefMode = scaleTaskAttr->scaleCoefMode;
    vgsTask.stImgIn.enModId = HI_ID_VPSS;
    vgsTask.stImgIn.u32PoolId = scaleTaskAttr->vgsTaskAttr.frameDataIn.u32PoolId;
    ret = MAPI_VGS_SetFrameInfo(&vgsTask.stImgIn.stVFrame, &scaleTaskAttr->vgsTaskAttr.frameDataIn);
    if (ret != HI_SUCCESS) {
        MAPI_ERR_TRACE(HI_MAPI_MOD_VGS, "MAPI_VGS_SetFrameInfo fail, ret:%x\n", ret);
        return ret;
    }

    vgsTask.stImgOut.enModId = HI_ID_VGS;
    vgsTask.stImgOut.u32PoolId = scaleTaskAttr->vgsTaskAttr.frameDataOut.u32PoolId;
    ret = MAPI_VGS_SetFrameInfo(&vgsTask.stImgOut.stVFrame, &scaleTaskAttr->vgsTaskAttr.frameDataOut);
    if (ret != HI_SUCCESS) {
        MAPI_ERR_TRACE(HI_MAPI_MOD_VGS, "MAPI_VGS_SetFrameInfo fail, ret:%x\n", ret);
        return ret;
    }

    ret = HI_MPI_VGS_AddScaleTask(vgsHdl, &vgsTask, scaleCoefMode);
    if (ret != HI_SUCCESS) {
        MAPI_ERR_TRACE(HI_MAPI_MOD_VGS, "HI_MPI_VGS_AddScaleTask fail, ret:%x\n", ret);
        return ret;
    }

    return HI_SUCCESS;
}


HI_S32 HI_MAPI_VGS_EndJob(HI_HANDLE vgsHdl)
{
    HI_S32 ret;
    CHECK_MAPI_BOOL_RET(HI_MAPI_MOD_VGS, vgsHdl != (HI_U32)HI_INVALID_HANDLE, HI_MAPI_VGS_EHANDLE_ILLEGAL);

    ret = HI_MPI_VGS_EndJob(vgsHdl);
    if (ret != HI_SUCCESS) {
        MAPI_ERR_TRACE(HI_MAPI_MOD_VGS, "HI_MAPI_VGS_EndJob fail, ret:%x\n", ret);
        return ret;
    }

    return HI_SUCCESS;
}

HI_S32 HI_MAPI_VGS_CanceJob(HI_HANDLE vgsHdl)
{
    HI_S32 ret;
    CHECK_MAPI_BOOL_RET(HI_MAPI_MOD_VGS, vgsHdl != (HI_U32)HI_INVALID_HANDLE, HI_MAPI_VGS_EHANDLE_ILLEGAL);

    ret = HI_MPI_VGS_CancelJob(vgsHdl);
    if (ret != HI_SUCCESS) {
        MAPI_ERR_TRACE(HI_MAPI_MOD_VGS, "HI_MAPI_VGS_CanceJob fail, ret:%x\n", ret);
        return ret;
    }

    return HI_SUCCESS;
}
